package net.fornwall.eclipsecoder.javasupport;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;

/**
 * A class for launching JUnit.
 */
class Launcher {

    protected ICompilationUnit unit;

    /**
     * Create a new launcher for a new java class file (ICompilationUnit).
     * 
     * @param unit
     *            The .java file to run.
     */
    public Launcher(ICompilationUnit unit) {
        this.unit = unit;
    }

    /**
     * 
     */
    /*
     * protected String getMethodName() { String methodName = null; try { IType[] types =
     * unit.getAllTypes(); for (int i = 0; i < types.length; i++) { if (types[i].isClass()) {
     * IMethod method = types[i].getMethod("test0", new String[] {}); methodName =
     * method.getElementName(); } } // IJavaElement method = unit.getElementAt(34); if
     * (method.getElementType() == IJavaElement.METHOD) { // methodName = method.getElementName(); } }
     * catch (JavaModelException e1) { e1.printStackTrace(); } return methodName; }
     */

    private ILaunchConfigurationWorkingCopy createLaunchWorkingCopy() throws CoreException {
        ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
        ILaunchConfigurationType configType = manager.getLaunchConfigurationType(getLauncherType());
        ILaunchConfigurationWorkingCopy workingCopy = getExistingConfig(manager, configType);

        if (workingCopy == null) {
            workingCopy = configType.newInstance(null, getLauncherName());
        }
        return workingCopy;
    }

    private String getClassName() {
        String className = null;
        try {
            IType type = this.unit.getTypes()[0];
            className = type.getFullyQualifiedName();
        } catch (JavaModelException e) {
            e.printStackTrace();
        }
        return className;
    }

    private ILaunchConfigurationWorkingCopy getExistingConfig(ILaunchManager manager,
            ILaunchConfigurationType type) throws CoreException {
        ILaunchConfigurationWorkingCopy workingCopy = null;

        ILaunchConfiguration[] configurations = manager.getLaunchConfigurations(type);
        for (int i = 0; i < configurations.length; i++) {
            if (configurations[i].getName().equals(getLauncherName())) {
                workingCopy = configurations[i].getWorkingCopy();
                break;
            }
        }

        return workingCopy;
    }

    /**
     * Return launch configuration name
     */
    protected String getLauncherName() {
        return "RUN JUnit";
    }

    protected String getLauncherType() {
        return "org.eclipse.jdt.junit.launchconfig";
    }

    private String getProjectName() {
        // return unit.getJavaProject().getElementName();
        return unit.getJavaProject().getElementName();
    }

    private void launchDebug(String projectName, String className) {
        try {
            ILaunchConfigurationWorkingCopy workingCopy = createLaunchWorkingCopy();

            workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
                    projectName);
            workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
                    className);
            // workingCopy.setAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, "");

            ILaunchConfiguration configuration = workingCopy.doSave();

            DebugUITools.launch(configuration, ILaunchManager.RUN_MODE);
        } catch (CoreException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        String projectName = getProjectName();
        String className = getClassName();
        launchDebug(projectName, className);
    }
}
